home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / BSSLEEP.C < prev    next >
C/C++ Source or Header  |  1993-05-30  |  7KB  |  212 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    bssleep.c
  5. //   Title:    Base library
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains to delay program execution.
  25. //    Under OS/2, a delay of 0 causes the current thread to give up its time
  26. //    slice.
  27. //
  28. //    This code is not implemented under SCO UNIX or Windows. 
  29. //    Also, the MSC compiler does not provide a startup pragma so initialization
  30. //    is not performed correctly with that compiler.
  31. //
  32. //    The code in this module should be written entirely in C.
  33. //    Do not use any C++ constructs.
  34. //
  35. //    This module is portable to:
  36. //        DOS 3.X+
  37. //        OS/2 2.X+
  38. //
  39. //    The following compilers are supported:
  40. //        Borland C++ 3.1 for DOS
  41. //        Borland C++ 1.0 for OS/2 2.X
  42. //
  43. //----------------------------------------------------------------------------
  44. #include <bs.h>
  45.  
  46.  
  47. //----------------------------------------------------------------------------
  48. //    Prototypes
  49. //----------------------------------------------------------------------------
  50. #if OS_DOS
  51. static void near dummy(void);
  52. static USHORT FN_A ReadTimer(void);
  53. #endif
  54.  
  55. //----------------------------------------------------------------------------
  56. //    Local Data
  57. //----------------------------------------------------------------------------
  58. #if OS_DOS
  59. static ULONG ulMultiplier = 1193*2L;
  60. #endif
  61.  
  62.  
  63. //----------------------------------------------------------------------------
  64. //   Description:    Dummy function. Does nothing but waste time
  65. //    Parameters:
  66. //       Globals:
  67. //       Returns:    TRUE if successful.
  68. //----------------------------------------------------------------------------
  69. #if OS_DOS
  70. static void near dummy(void)
  71. {
  72.     return ;
  73. }
  74. #endif
  75.  
  76.  
  77. //----------------------------------------------------------------------------
  78. //   Description:    Obtain the complement of the value in timer 0.  The
  79. //                        complement is used so that the timer will appear to
  80. //                        count up rather than down.  The value returned will
  81. //                        range from 0 to 0xffff.
  82. //    Parameters:
  83. //       Globals:    
  84. //       Returns:    The complement of the value in timer 0.
  85. //----------------------------------------------------------------------------
  86. #if OS_DOS
  87. static USHORT FN_A ReadTimer(void)
  88. {
  89.     asm {
  90.         pushf                               // Save interrupt flag
  91.         cli                                 // Disable interrupts
  92.       mov      al,0h                      // Latch timer 0                             
  93.       out    43h,al       
  94.         }
  95.     dummy();                               // Waste some time
  96.     asm {
  97.         in   al,40h                         // Counter --> bx                            
  98.         mov  bl,al                          // LSB in BL
  99.         }
  100.    dummy();                                 // Waste some time
  101.     asm {
  102.         in       al,40h
  103.         mov      bh,al                      // MSB in BH                                 
  104.         not      bx                         // Need ascending counter                    
  105.         popf                                // Restore interrupt flag                    
  106.         }
  107.    return _BX;
  108. }
  109. #endif
  110.  
  111.  
  112. //----------------------------------------------------------------------------
  113. //   Description:    The current thread of execution is suspended for the 
  114. //                          specified number of milliseconds.
  115. //    Parameters:    ulMSecs        Number of milleseconds to sleep.
  116. //                                        If 0, the current time-slice is given up.
  117. //                                        Default is 0.
  118. //       Globals:    
  119. //       Returns:    void
  120. //----------------------------------------------------------------------------
  121. VOID FN_E Sleep(ULONG ulMSecs)
  122. {
  123. #if OS_OS2 || OS_PM
  124.  
  125.     // If sleep == 0L, OS/2 gives up current time slice
  126.     DosSleep(ulMSecs);
  127.  
  128. #elif OS_WINDOWS
  129.  
  130.     // This should find a way to give up the time slice or whatever.
  131.     NOTUSED(ulMSecs);
  132.  
  133. #elif OS_DOS
  134.     ULONG stop;
  135.     USHORT cur, prev;
  136.  
  137.     if (!ulMSecs)                                // Early out!
  138.         {
  139.         _asm {
  140.             mov ax, 1680h                        // Give Window's the time slice
  141.             int 2fh
  142.             }
  143.         return ;
  144.         }
  145.     stop = (prev = ReadTimer()) + (ulMSecs * ulMultiplier);
  146.     while ((cur = ReadTimer()) < stop)
  147.       {
  148.       if (cur < prev)                         // Check for timer wraparound 
  149.          {
  150.          if (stop < 0x10000L)
  151.             break;
  152.          stop -= 0x10000L;
  153.          }
  154.       prev = cur;
  155.       }
  156. #else                                                // Unix! (second resolution only)
  157.     sleep((ulMSecs+999L)/1000L);
  158. #endif
  159.     return ;
  160. }
  161.  
  162.  
  163. //----------------------------------------------------------------------------
  164. //   Description:    Determine the multiplier required to convert milliseconds
  165. //                        to an equivalent interval timer value.  Interval timer 0
  166. //                        is normally programmed in mode 3 (square wave), where
  167. //                        the timer is decremented by two every 840 nanoseconds;
  168. //                        in this case the multiplier is 2386.  However, some
  169. //                        programs and device drivers reprogram the timer in mode 2,
  170. //                        where the timer is decremented by one every 840 ns; in this
  171. //                        case the multiplier is halved, i.e. 1193.
  172. //
  173. //                        When the timer is in mode 3, it will never have an odd value.
  174. //                        In mode 2, the timer can have both odd and even values.
  175. //                        Therefore, if we read the timer 100 times and never
  176. //                        see an odd value, it's a pretty safe assumption that
  177. //                        it's in mode 3.  This is the method used in timer_init.
  178. //    Parameters:
  179. //       Globals:    
  180. //       Returns:    void
  181. //----------------------------------------------------------------------------
  182. #if OS_DOS
  183. VOID FN SleepInitialize(void)
  184. {
  185.     SHORT i;
  186.     for (i = 0; i < 100; i++)
  187.       if ((ReadTimer() & 1) == 0)         // ReadTimer() returns complement 
  188.           {
  189.          ulMultiplier = 1193L;
  190.          return;
  191.          }
  192.     return ;
  193. }
  194. #endif
  195.  
  196.  
  197. //----------------------------------------------------------------------------
  198. //   Description:    Run standard test suite
  199. //    Parameters:    sTest        Number of milliseconds to sleep.
  200. //       Returns:    TRUE if successful.
  201. //----------------------------------------------------------------------------
  202. #if COMPILE_TEST
  203. BOOL FN SleepTest(SHORT sTest)
  204. {
  205.     Sleep((ULONG)sTest);
  206.     return TRUE;
  207. }
  208. #endif
  209. //----------------------------------------------------------------------------
  210. //------------------------------- End of File --------------------------------
  211. //----------------------------------------------------------------------------
  212.